﻿// OpenZapper
// http://openzapper.codeplex.com/
// Appache License Version 2.0 

using System;
using System.IO;

namespace NeoRife2OpenZapper_DataConvertor
{
    class Program
    {
        static void Main(string[] args)
        {

            string sNeoRifeDataFolder       = @"C:\Program Files (x86)\FreqGen\data";
            string sOpenZapperOutputFolder  = @"d:\tmp\OpenZapper";
            int defaultCycleRatio           = 50;
            const int DEFAULT_DURATION      = 180;
            bool bIsRandom = true;

            for (int i = 0; i < args.Length; i++)
            {
                if(args[i].Contains("-h") || args[i].Contains("/?") || args[i].Contains("-?") || args[i].Contains("/h") || args[i].Contains("/help") || args[i].Contains("-help"))
                {
                    DisplayHelp();
                    Environment.Exit(0);
                }
                if(args[i].Contains("-i") && ((args.Length - 1) >= (i + 1)))
                {
                    if(Directory.Exists(args[i + 1]) == false)
                    {
                        Console.WriteLine("input folder " + args[i + 1] + " doesn't exist");
                    }
                    else
                    {
                        sNeoRifeDataFolder = args[i + 1];
                    }
                    continue;
                }
                if(args[i].Contains("-o") && ((args.Length - 1) >= (i + 1)))
                {
                    sOpenZapperOutputFolder = args[i + 1];
                    continue;
                }
                if(args[i].Contains("-s"))
                {
                    bIsRandom = false;
                    continue;
                }
                if(args[i].Contains("-r"))
                {
                    bIsRandom = true;
                    continue;
                }
                if(args[i].Contains("-cr") && ((args.Length - 1) >= (i + 1)))
                {
                    if( false == int.TryParse(args[ i + 1 ], out defaultCycleRatio))
                    {
                        defaultCycleRatio = 50;
                    }
                    else
                    {
                        if( defaultCycleRatio > 100)
                        {
                            defaultCycleRatio = 100;
                        }
                        if(defaultCycleRatio < 0)
                        {
                            defaultCycleRatio = 0;
                        }
                    }
                    continue;
                }
            }


            

            if(Directory.Exists(sOpenZapperOutputFolder) == false)
            {
                try
                {
                    Directory.CreateDirectory(sOpenZapperOutputFolder);
                }
                catch(Exception ex)
                {
                    Console.WriteLine("ERROR:" + ex.Message);
                }
            }
            

            if( Directory.Exists(sNeoRifeDataFolder))
            {
                string[] dataFiles = Directory.GetFiles(sNeoRifeDataFolder);
                foreach(string filename in dataFiles)
                {
                    if(File.Exists(filename))
                    {
                        FileInfo fi = new FileInfo(filename);
                        if(fi.Length > 0)
                        {
                            using (StreamReader sr = new StreamReader(filename))
                            {
                                using (StreamWriter sw = new StreamWriter(Path.Combine(sOpenZapperOutputFolder, fi.Name + " .txt"),false))
                                {
                                    Console.WriteLine("Processing file " + filename);
                                    if( bIsRandom == true)
                                    {
                                        sw.WriteLine("Random");
                                    }
                                    else
                                    {
                                        sw.WriteLine("Sequential");
                                    }
                                    while(sr.EndOfStream == false)
                                    {
                                        string line  = sr.ReadLine();
                                        line = line.TrimStart();
                                        if( line.StartsWith("#") == false)
                                        {
                                            line = line.Replace(" ", "");
                                            string[] split = line.Split(',');
                                            if(split.Length == 2)
                                            {
                                                bool bFrequencyRange = false;
                                                double frequency = 1.0;
                                                split[0] = split[0].Replace("*", "");
                                                split[0] = split[0].Replace(".", ",");
                                                if(split[0].Contains("K"))
                                                {
                                                    split[0] = ConvertValue(split[0], "K", 1000);
                                                }
                                                if(split[0].Contains("-"))
                                                {
                                                    bFrequencyRange = true;
                                                }
                                                else
                                                {
                                                    if(Double.TryParse(split[0],out frequency) == false)
                                                    {
                                                        Console.WriteLine("Couldn't parse frequency for the following line:" + line + " => Using default value 1");
                                                    }
                                                }
                                                
                                                double duration = DEFAULT_DURATION;
                                                if(split[1].Contains("min"))
                                                {
                                                    split[1] = ConvertValue(split[1], "min", 60);
                                                }
                                                if(split[1].Contains("sec"))
                                                {
                                                    split[1] = ConvertValue(split[1], "sec", 1);
                                                }
                                                if(Double.TryParse(split[1], out duration) == false)
                                                {
                                                    Console.WriteLine("Couldn't parse duration for the following line:" + line + " => Using default value " + DEFAULT_DURATION);
                                                }

                                                if( bFrequencyRange == false)
                                                {
                                                    sw.WriteLine((int)frequency + "|" + defaultCycleRatio + "|" + (int)duration);
                                                }
                                                else
                                                {
                                                    string[] sFrequencyRange = split[0].Split('-');
                                                    if(sFrequencyRange.Length == 2)
                                                    {
                                                        Double iFrequencyStart = 0;
                                                        Double iFrequencyStop = 0;

                                                        Double.TryParse(sFrequencyRange[0], out iFrequencyStart);
                                                        Double.TryParse(sFrequencyRange[1], out iFrequencyStop);
                                                        if(iFrequencyStart < iFrequencyStop)
                                                        {
                                                            int frequencyStepDuration = (int)duration / (int)(iFrequencyStop - iFrequencyStart);
                                                            if(frequencyStepDuration < 1)
                                                            {
                                                                frequencyStepDuration = 1;
                                                            }
                                                             for (int i = (int)iFrequencyStart; i < ((int)iFrequencyStop + 1); i++)
                                                            {
                                                                sw.WriteLine((int)i + "|" + defaultCycleRatio + "|" + (int)frequencyStepDuration);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            Console.WriteLine("Error On line " + line + " Invalid input frequency");
                                                        }
                                                    }
                                                    else 
                                                    {
                                                        Console.WriteLine("Error On line " + line + " cannot convert Frequency Range value");
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                Console.WriteLine("Line " + line + " is not supported");
                                            }
                                        }
                                    }
                                    sw.WriteLine();
                                    Console.WriteLine("Processing file " + filename + " Done");
                                }
                            }
                        }
                        else
                        {
                            Console.WriteLine("Warning: Input file " + filename + " size if 0, skipping");
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("ERROR: Input folder " + sNeoRifeDataFolder + " does not exist");
                Environment.Exit(-1);
            }
            Console.WriteLine("Processing finish");
        }

        private static string ConvertValue(string value, string sufix, int multiplier)
        {
            value = value.Replace(sufix, "");
            Double dvalue;
            Double.TryParse(value, out dvalue);
            string svalue = ((int)(dvalue * multiplier)).ToString();
            return svalue;
        }

        private static void  DisplayHelp()
        {
            Console.Clear();
            Console.WriteLine("NeoRifeToOpenZapper converter command line Help");
            Console.WriteLine(@"-i [input NeoRife data folder] => (default is C:\Program Files (x86)\FreqGen\data)");
            Console.WriteLine(@"-o [OutputFolder] => Output folder that will contain the converted files usable by OpenZapper (default is d:\tmp\OpenZapper\)");
            Console.WriteLine(@"-r Generates a random access frequency convertion");
            Console.WriteLine(@"-s Generates a sequential access frequency convetion");
            Console.WriteLine(@"-cr [Cycle ratio] Interger [0-100] defining the PWM cycle ratio in percentage (default = 50)");
        }

    }
}
